#pragma once
#include<iostream>
#include <string.h>
#include<cassert>
using namespace std;

namespace su
{
	//增删查改，实现各类函数
	
	template<typename T>
	class vector
	{
		typedef T* iterator;
		typedef const T* const_iterator;

	public:
		vector()
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{}

		template <class InputIterator>//模板构造的类型一般要与该类模板大致相同，不然可能会有截断或者报错
		vector(InputIterator first, InputIterator last)
			: _start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			//模板构造一个序列
			int j = last - first;

		/*	_start = new T[j];
			_finish = _start;
			_end_of_storage = _start + j;*///没必要重新创建空间给_start,其本来就可自动扩容
			for (int i = 0; i < j; i++)
			{
				push_back(first[i]);
			}
		}

		//拷贝构造，赋值，析构
		vector(const vector<T>& v)
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			vector<T> tmp(v.begin(), v.end());
			swap(tmp);
		}

		vector(int n, const T& val = T())//内置类型也是又构造函数的，这里传的是任意对象的参数缺省
			:_start(nullptr)
			, _finish(nullptr)
			, _end_of_storage(nullptr)
		{
			reserve(n);
			for (int i = 0; i < n; i++)
			{
				insert(end(), val);
			}
		}
		~vector()
		{
			if (_start)
			{
				delete[] _start;
				_start = _finish = _end_of_storage = nullptr;
			}
		}

		//赋值
		vector<T>& operator=(vector<T> v)//直接传进来拷贝拷贝的话就不需要里面进行拷贝构造吗，而且还需要判断是否相同的导致的多次析构问题
		{
			//if(this!=&v)这个就无需判断了，因为一定不同
			swap(v);
			return *this;
		}

		//迭代器
		iterator begin()
		{
			return _start;
		}
		const_iterator begin() const
		{
			return _start;
		}
		iterator end()
		{
			return _finish;
		}
		const_iterator end() const
		{
			return _finish;
		}


		//判断容器
		size_t _size()
		{
			return _finish - _start;
		}

		size_t _capacity()
		{
			return _end_of_storage - _start;
		}

		T& operator[] (size_t i)
		{
			assert(i < _size());
			return _start[i];
		}
		const T& operator[] (size_t i) const 
		{
			assert(i < _size());
			return _start[i];
		}

		//交换
		void swap(vector<T>& v)
		{
			std::swap(_start, v._start);
			std::swap(_finish, v._finish);
			std::swap(_end_of_storage, v._end_of_storage);
		}

		//清空
		void clear()
		{
			_finish = _start;
		}

		//扩容
		void reserve(size_t n)
		{
			size_t size = _size();
			if (n > _capacity())
			{
				//vector<T> tmp;
				//tmp._start = new T[n];
				T* tmp= new T[n];
				if (_start)
				{
					//memcpy(tmp, _start, size * sizeof(T));//这个memcpy是一个浅拷贝，对于深一层次的深拷贝会有问题，如vector的类型是vector或string这些管理资源的类型

					//故需要利用到循环赋值来解决这个深层次的深拷贝问题，因为其所实现的赋值也是深拷贝
					for (size_t i = 0; i < size; i++)
					{
						//tmp._start[i] = _start[i];
						tmp[i] = _start[i];

					}
					delete[] _start;
				}
				//_start = tmp._start;
				_start = tmp;
				/*_finish = _size();*/	//这个就会由问题，因为_size()用的就是两个指针相减，而这个时候_start已经发生变化了,故需要提前保存你的szie
                _finish = _start + size;
			    _end_of_storage = _start + n;
			}
			
		}


		void resize(size_t n,T x = T())
		{
			//判断扩容
			if (n > _capacity())
			{
				reserve(n);
			}

			//判断比size大还是小
			if (n > _size())
			{
				for (size_t i = _size(); i < n; i++)
				{
					_start[i] = x;
				}
			}
			_finish = _start+n;
			
		}

		//插入
		void push_back(const T& x)
		{
			//判断容量
			if (_finish == _end_of_storage)
			{
				size_t new_capacity = _size() == 0 ? 4 : 2 * _capacity();
				reserve(new_capacity);
			}
			_start[_size()] = x;
			_finish++;
		}

		void pop_back()
		{
			if(_finish>_start)
				_finish--;
		}

		iterator insert(iterator pos, const T& val)
		{
			assert(pos >= _start && pos <= _finish);//支持尾插
			//扩容
			if (_finish == _end_of_storage)
			{
				size_t len = pos - _start;

				size_t new_capacity = _size() == 0 ? 4 : 2 * _capacity();
				reserve(new_capacity);				//扩容可能导致迭代器失效，因为原来pos的地址已经销毁
				pos = _start + len;

			}
			//移动数据
			iterator end = _finish;
			while (end > pos)
			{
				*end = *(end - 1);
				end--;
			}

			*pos = val;
			_finish++;

			return pos;//返回最新插入元素的位置
		}
		iterator erase(iterator pos)
		{
			assert(pos >= _start && pos < _finish);
			iterator it = pos+1;
			while (it!=_finish)
			{
				*(it - 1) = *it;
				it++;
			}
			_finish--;
			return pos;//这里返回的是原来pos的下一位，即之前是啥就是啥，erase没有删除，就没有野指针的迭代器失效
			
		}


		bool empty()
		{
			return _size() == 0;
		}

	private:
		iterator _start;
		iterator _finish;
		iterator _end_of_storage;
	};
}